//
// Created on 2025/10/16.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".

#include "JPushPlugin.h"
#include "CordovaViewController.h"
#include "cJSON.h"

REGISTER_PLUGIN_CLASS(JPushPlugin)

bool JPushPlugin::execute(const string&  action, cJSON* args, CallbackContext cbc) 
{
    if(action == "onArKTsResult") {
        return onArKTsResult(args);
    }
    
    if(action == "init") {
        m_cbc = cbc;
        executeArkTs("./JPush/JPushAction/JPushPlugin", 0, "", "JPushPlugin", cbc);
        pushInfoBeforeInit();
        return true;
    }
    
    if(action == "getRegistrationID") {
        m_cbc = cbc;
        executeArkTs("./JPush/JPushAction/JPushPlugin", 1, "", "JPushPlugin", cbc);
        return true;
    }
    
    if(action == "stopPush") {
         m_cbc = cbc;
        executeArkTs("./JPush/JPushAction/JPushPlugin", 2, "", "JPushPlugin", cbc);
        return true;
    }
    
    if(action == "resumePush") {
         m_cbc = cbc;
        executeArkTs("./JPush/JPushAction/JPushPlugin", 3, "", "JPushPlugin", cbc);
        return true;
    }
    
    if(action == "isPushStopped") {
         m_cbc = cbc;
        executeArkTs("./JPush/JPushAction/JPushPlugin", 4, "", "JPushPlugin", cbc);
        return true;
    }
    
    if(action == "addTags") {
        m_cbc = cbc;
        cJSON* pJson = cJSON_GetArrayItem(args, 0);
        if(pJson != nullptr) {
            char* pStr = cJSON_Print(pJson);
            executeArkTs("./JPush/JPushAction/JPushPlugin", 5, pStr, "JPushPlugin", cbc);
            free(pStr);
        }
        return true;
    }
    
    if(action == "deleteTags") {
        m_cbc = cbc;
        cJSON* pJson = cJSON_GetArrayItem(args, 0);
        if(pJson != nullptr) {
            char* pStr = cJSON_Print(pJson);
            executeArkTs("./JPush/JPushAction/JPushPlugin", 6, pStr, "JPushPlugin", cbc);
            free(pStr);
        }
        return true;
    }
    if(action == "setTags") {
        m_cbc = cbc;
        cJSON* pJson = cJSON_GetArrayItem(args, 0);
        if(pJson != nullptr) {
            char* pStr = cJSON_Print(pJson);
            executeArkTs("./JPush/JPushAction/JPushPlugin", 7, pStr, "JPushPlugin", cbc);
            free(pStr);
        }
        return true;
    }
    if(action == "checkTagBindState") {
        m_cbc = cbc;
        cJSON* pJson = cJSON_GetArrayItem(args, 0);
        if(pJson != nullptr) {
            char* pStr = cJSON_Print(pJson);
            executeArkTs("./JPush/JPushAction/JPushPlugin", 8, pStr, "JPushPlugin", cbc);
            free(pStr);
        }
        return true;
    }
    if(action == "checkTagBindState") {
        m_cbc = cbc;
        cJSON* pJson = cJSON_GetArrayItem(args, 0);
        if(pJson != nullptr) {
            char* pStr = cJSON_Print(pJson);
            executeArkTs("./JPush/JPushAction/JPushPlugin", 8, pStr, "JPushPlugin", cbc);
            free(pStr);
        }
        return true;
    }
    if(action == "getAllTags") {
        m_cbc = cbc;
        cJSON* pJson = cJSON_GetArrayItem(args, 0);
        if(pJson != nullptr) {
            char* pStr = cJSON_Print(pJson);
            executeArkTs("./JPush/JPushAction/JPushPlugin", 9, pStr, "JPushPlugin", cbc);
            free(pStr);
        }
        return true;
    }
    if(action == "cleanTags") {
        m_cbc = cbc;
        cJSON* pJson = cJSON_GetArrayItem(args, 0);
        if(pJson != nullptr) {
            char* pStr = cJSON_Print(pJson);
            executeArkTs("./JPush/JPushAction/JPushPlugin", 10, pStr, "JPushPlugin", cbc);
            free(pStr);
        }
        return true;
    }
    if(action == "setAlias") {
        m_cbc = cbc;
        cJSON* pJson = cJSON_GetArrayItem(args, 0);
        if(pJson != nullptr) {
            char* pStr = cJSON_Print(pJson);
            executeArkTs("./JPush/JPushAction/JPushPlugin", 11, pStr, "JPushPlugin", cbc);
            free(pStr);
        }
        return true;
    }
    if(action == "getAlias") {
        m_cbc = cbc;
        cJSON* pJson = cJSON_GetArrayItem(args, 0);
        if(pJson != nullptr) {
            char* pStr = cJSON_Print(pJson);
            executeArkTs("./JPush/JPushAction/JPushPlugin", 12, pStr, "JPushPlugin", cbc);
            free(pStr);
        }
        return true;
    }
    if(action == "deleteAlias") {
        m_cbc = cbc;
        cJSON* pJson = cJSON_GetArrayItem(args, 0);
        if(pJson != nullptr) {
            char* pStr = cJSON_Print(pJson);
            executeArkTs("./JPush/JPushAction/JPushPlugin", 13, pStr, "JPushPlugin", cbc);
            free(pStr);
        }
        return true;
    }
    if(action == "setMobileNumber") {
        m_cbc = cbc;
        cJSON* pJson = cJSON_GetArrayItem(args, 0);
        if(pJson != nullptr) {
            char* pStr = cJSON_Print(pJson);
            executeArkTs("./JPush/JPushAction/JPushPlugin", 14, pStr, "JPushPlugin", cbc);
            free(pStr);
        }
        return true;
    }
    if(action == "setBadgeNumber") {
         m_cbc = cbc;
        cJSON* pJson = cJSON_GetArrayItem(args, 0);
        if(pJson != nullptr && pJson->type == cJSON_Number) {
            string strNumber = to_string(pJson->valueint);
            executeArkTs("./JPush/JPushAction/JPushPlugin", 15, strNumber.c_str(), "JPushPlugin", cbc);
        }
        return true;
    }
    
    if(action == "clearNotificationById") {
        cJSON* pJson = cJSON_GetArrayItem(args, 0);
        if(pJson != nullptr && pJson->type == cJSON_String) {
            string strMsgeId = pJson->valuestring;
            executeArkTs("./JPush/JPushAction/JPushPlugin", 16, strMsgeId.c_str(), "JPushPlugin", cbc);
        }
        return true;
    }
    
    if(action == "clearAllNotification") {
        executeArkTs("./JPush/JPushAction/JPushPlugin", 17, "", "JPushPlugin", cbc);
        return true;
    }
    
    return true;
}

bool JPushPlugin::onArKTsResult(cJSON* args)
{
    cJSON* json = cJSON_GetObjectItem(args, "content");
    string strContent = "";
    if(json != NULL) {
        strContent = json->valuestring;
    }
    cJSON* pResult = cJSON_GetObjectItem(args, "result");
    if(strContent == "onRegister" ) {
        cJSON* pRet = cJSON_GetArrayItem(pResult, 0);
        if(pRet != nullptr && pRet->type == cJSON_String) {
            string data = pRet->valuestring;
            string jsExec = "window.plugins.jPushPlugin.receiveRegistrationIdInAndroidCallback(";
            jsExec += data + ")";
            ((CordovaViewController*)Application::g_cordovaViewController)->addJavaScript(m_cbc.getWebTag(), jsExec);
        }
    }
    
    if(strContent == "onConnected" ) {
        if(pResult != NULL && pResult->type == cJSON_Array) {
            cJSON* pRet = cJSON_GetArrayItem(pResult, 0);
            if(pRet != NULL && pRet->type == cJSON_String) {
                string strRet = pRet->valuestring;
                m_cbc.success(strRet);
            }
        }
    }
    
    if(strContent == "getRegistrationID" || strContent == "isPushStopped") {
        if(pResult != NULL && pResult->type == cJSON_Array) {
            cJSON* pRet = cJSON_GetArrayItem(pResult, 0);
            if(pRet != NULL && pRet->type == cJSON_String) {
                string strRet = pRet->valuestring;
                m_cbc.success(strRet);
            }
        }
    }

    if(strContent == "onTagOperatorResult" || strContent == "onAliasOperatorResult" || strContent == "onMobileNumberOperatorResult") {
        if(pResult != NULL && pResult->type == cJSON_Array) {
            cJSON* pRet = cJSON_GetArrayItem(pResult, 0);
            if(pRet != NULL) {
                m_cbc.success(pRet);
            }
        }
    }
    
    
    if(strContent == "onConnected" || strContent == "stopPush" || strContent == "resumePush") {
       m_cbc.success();
    }
    
    if(strContent == "onClickMessage") {
        cJSON* pRet = cJSON_GetArrayItem(pResult, 0);
        if(pRet != nullptr && pRet->type == cJSON_String) {
            string data = pRet->valuestring;
            string jsExec = "window.plugins.jPushPlugin.receiveInAppMessageClickCallback(";
            jsExec += data + ")";
            ((CordovaViewController*)Application::g_cordovaViewController)->addJavaScript(m_cbc.getWebTag(), jsExec);
        }
    }
    
    if(strContent == "onArrivedMessage" || strContent == "onCustomMessage" || strContent == "onJMessageExtra"  || strContent == "onJMessageVoIP") {
        cJSON* pRet = cJSON_GetArrayItem(pResult, 0);
        if(pRet != nullptr && pRet->type == cJSON_String) {
            string data = pRet->valuestring;
            string jsExec = "window.plugins.jPushPlugin.receiveMessageInAndroidCallback(";
            jsExec += data + ")";
            ((CordovaViewController*)Application::g_cordovaViewController)->addJavaScript(m_cbc.getWebTag(), jsExec);
        }
    }
    
    if(strContent == "onUnShowMessage") {
       //TODO：暂不支持通知到JS侧
    }
    return true;
}

void JPushPlugin::pushInfoBeforeInit() 
{
    if(!Application::g_strPushInfoBeforeInit.empty()) {
        cJSON* pAllJson = cJSON_Parse(Application::g_strPushInfoBeforeInit.c_str());
        if(cJSON_GetObjectItem(pAllJson, "result")) {  //启动前保存的推送，包含json的所有数据因为缓存全局变量中了，没有调用插件，启动后直接调用了插件
            cJSON* json = cJSON_GetObjectItem(pAllJson, "result");
            if(json != NULL && json->type == cJSON_Array) {
                int count = cJSON_GetArraySize(json);
                string type;
                if(count > 0) {
                    type = cJSON_GetArrayItem(json, 0)->valuestring;
                }
                string data;    
                if(count > 0) {
                    data = cJSON_GetArrayItem(json, 1)->valuestring;
                }
                string jsExec = "cordova.fireDocumentEvent('huaweiMessageReceived',";
                jsExec += data + ")";
                ((CordovaViewController*)Application::g_cordovaViewController)->addJavaScript(m_cbc.getWebTag(), jsExec);
            }
        }        
        Application::g_strPushInfoBeforeInit = "";
    }
}